package collection;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Map 是一种把键对象和值对象映射的集合，它的每一个元素都包含一对键对象和值对象
 */
public class MapDemo {
    /**
     * HashMap            //Map基于散列表的实现(无序的)。插入和查询“键值对”的开销是固定的。
     * LinkedHashMap      //类似于HashMap，但是迭代遍历它时，取的顺序是其插入次序(有序的)。只比HashMap慢一点。而在迭代访问时发而更快，因为它使用链表维护内部次序。
     * TreeMap            //底层是二叉树数据结构，线程不同步，可用于给Map集合中的键进行排序。
     * HashTable          //是(线程安全的),效率低，主要区别Hashtable不可以存储null键和null值,HashMap可以存储null键和null值。
     * ConcurrentHashMap  //ConcurrentHashMap通常只被看做并发效率更高的Map，用来替换其他线程安全的Map容器，比如Hashtable和Collections.synchronizedMap。
     * IdentifyHashMap    //使用==代替equals()对“键”作比较的hash map
     * ArrayMap           //ArrayMap是一个<key,value>映射的数据结构，它设计上更多的是考虑内存的优化，内部是使用两个数组进行数据存储，一个数组记录key的hash值，另外一个数组记录Value值，它和SparseArray一样，也会对key使用二分法进行从小到大排序，在添加、删除、查找数据的时候都是先使用二分查找法得到相应的index，然后通过index来进行添加、查找、删除等操作，所以，应用场景和SparseArray的一样，如果在数据量比较大的情况下，那么它的性能将退化至少50%。
     * SparseArray        //SparseArray比HashMap更省内存，在某些条件下性能更好，主要是因为它避免了对key的自动装箱（int转为Integer类型），它内部则是通过两个数组来进行数据存储的，一个存储key，另外一个存储value，为了优化性能，它内部对数据还采取了压缩的方式来表示稀疏数组的数据，从而节约内存空间。
     *
     * HashMap可以存储null键值对，键和值都可以是null，但如果添加的键值对的键相同，则后面添加的键值对会覆盖前面的键值对，即之后存储后添加的键值对；
     */
    public static void main(String[] args) {
        /*
         * Object put(Object key, Object value)： 向集合中加入元素
         * Object remove(Object key)： 删除与KEY相关的元素
         * void putAll(Map t)：  将来自特定映像的所有元素添加给该映像
         * void clear()：从映像中删除所有映射
         */
        int maxCount = 500;
        Map<Integer, String> hashMap = new HashMap<>();
        for (int i = 0; i < maxCount; i++) {
            hashMap.put(i, String.valueOf(i));
        }

        //遍历entrySet方式
        long start = System.currentTimeMillis();
        for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println("key: " + key + "value: " + value);
        }
        long end = System.currentTimeMillis();
        System.out.println("for-each方式 cost time : " + (end - start));


        //entrySet迭代器遍历方式(这个最快)
        long start1 = System.currentTimeMillis();
        Iterator<Map.Entry<Integer, String>> entries = hashMap.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry<Integer, String> entry = entries.next();
            Integer key = entry.getKey();
            String value = entry.getValue();
            System.out.println("key: " + key + "value: " + value);
        }
        long end1 = System.currentTimeMillis();
        System.out.println("entrySet iterator迭代器 cost time : " + (end1 - start1));


        //键找值遍历
        long start2 = System.currentTimeMillis();
        for (Integer key : hashMap.keySet()) {
            String value = hashMap.get(key);
            System.out.println( "key: " + key + "value: " + value);
        }
        long end2 = System.currentTimeMillis();
        System.out.println( "键找值遍历 cost time : " + (end2 - start2));

        //keySet迭代器遍历
        long start3 = System.currentTimeMillis();
        Iterator<Integer> iterator=hashMap.keySet().iterator();
        while (iterator.hasNext()) {
            Integer key=iterator.next();
            String  value=hashMap.get(key);
            System.out.println( "key: " + key +"value: "+value);
        }
        long end3 = System.currentTimeMillis();
        System.out.println( "keySet iterator迭代器 cost time : " + (end3 - start3));
    }
}
